package com.ruoyi.app.controller.business.customer;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.ruoyi.business.base.PageParam;
import com.ruoyi.business.customer.domain.*;
import com.ruoyi.business.customer.domain.dto.JbCustomerDto;
import com.ruoyi.business.customer.domain.dto.JbCustomerListDto;
import com.ruoyi.business.customer.domain.dto.JbCustomerTransferDto;
import com.ruoyi.business.customer.domain.dto.JbCustomerUpdateDto;
import com.ruoyi.business.customer.domain.vo.CustomerDynamicListVo;
import com.ruoyi.business.customer.domain.vo.JbCustomerBelongToRecordVo;
import com.ruoyi.business.customer.domain.vo.JbCustomerListVo;
import com.ruoyi.business.customer.service.JbCustomerService;
import com.ruoyi.business.customer.service.JbFavoriteTableService;
import com.ruoyi.business.customer.service.JbFollowupRecordService;
import com.ruoyi.business.customer.service.JbOpportunityService;
import com.ruoyi.business.order.domain.JbOrder;
import com.ruoyi.business.order.domain.JbRefund;
import com.ruoyi.business.order.service.JbOrderService;
import com.ruoyi.business.order.service.JbRefundService;
import com.ruoyi.business.sundry.domain.JbBusinessOperRecord;
import com.ruoyi.business.sundry.service.JbBusinessOperRecordService;
import com.ruoyi.common.annotation.BusinessOperLog;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessErrorEnum;
import com.ruoyi.common.enums.BusinessOperModule;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.RoleEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.core.JoR;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 客户 Controller
 *
 * @author ruoyi
 * @date 2024-10-11
 */
@Api("客户")
@RestController
@RequestMapping("/app/customer")
public class AppJbCustomerController extends BaseController
{
    @Autowired
    private JbCustomerService service;
    @Autowired
    private JbFavoriteTableService jbFavoriteTableService;
    @Autowired
    private JbOpportunityService jbOpportunityService;
    @Autowired
    private JbFollowupRecordService jbFollowupRecordService;
    @Autowired
    private JbOrderService jbOrderService;
    @Autowired
    private JbRefundService jbRefundService;
    @Autowired
    private JbBusinessOperRecordService jbBusinessOperRecordService;
    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询客户列表
     */
    @ApiOperation("查询客户列表")
    @GetMapping("/list")
    public TableDataInfo list(PageParam page, JbCustomerListDto jbCustomerListDto)
    {
        //我的商机，筛选待确认
       // -- expiration_time=保护到期时间
       // -- order_count=成交次数
       // -- order_total_amount=成交总额
       // -- product_count=产品数量
       // -- last_create_time=最后成交时间
       // -- received_count=回款次数
       // -- payment_amount=回款金额
       // -- refund_count=退款次数
       // -- refund_amount=退款金额
       // -- record_count=跟进次数
       // -- notFollowingDay=未跟进天数
       // -- next_followup_time=下次跟进时间
       //
       // -- customer_name_pinyin=名称
       // -- customer_type=类型
       // -- customer_status=状态
       // -- opportunity_source=来源
       // -- customer_star_level=星级
       // -- latest_followup_time=最后跟进时间
       // -- create_time=创建时间
       // -- transfer_customer_time=获得时间
       // -- update_time=更新时间
       // -- order_count=成交次数
        jbCustomerListDto.setDataType(Constants.PUBLIC_NUMBER_0);
        //appSeniorListData接口是多个表联合查询，且获取其他表数据排序
        String sortKey =StringUtils.isNotBlank(page.getSortKey())? page.getSortKey():StringUtils.EMPTY;
        IPage<JbCustomerListVo> iPage = switch (sortKey)
        {
            case "expiration_time", "order_count","order_total_amount"
                    ,"product_count", "last_create_time","received_count"
                    ,"payment_amount", "refund_count","record_count"
                    ,"notFollowingDay", "next_followup_time"-> service.appSeniorListData(page, jbCustomerListDto);
            default -> service.seniorListData(page, jbCustomerListDto);
        };
        return JoR.getDataTable(iPage);
    }

    @ApiOperation("查询CRM统计")
    @GetMapping("/getCrmStatistics")
    public AjaxResult getCrmStatistics(PageParam page)
    {
        Long userId = getUserId();
        Map<String, Long> data = Maps.newHashMap();
        //客户新增
        long customerAdd = service.count(Wrappers.lambdaQuery(JbCustomer.class)
                .ge(StringUtils.isNotBlank(page.getStartTimeBuilder())
                        , JbCustomer::getCreateTime, page.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(page.getEndTimeBuilder())
                        , JbCustomer::getCreateTime, page.getEndTimeBuilder())
                .eq(ObjectUtils.isNotEmpty(userId)
                        , JbCustomer::getCreateBy, userId));
        //商机新增
        long opportUnityAdd = jbOpportunityService.count(Wrappers.lambdaQuery(JbOpportunity.class)
                .ge(StringUtils.isNotBlank(page.getStartTimeBuilder())
                        , JbOpportunity::getCreateTime, page.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(page.getEndTimeBuilder())
                        , JbOpportunity::getCreateTime, page.getEndTimeBuilder())
                .eq(ObjectUtils.isNotEmpty(userId)
                        , JbOpportunity::getCreateBy, userId));
        //跟进记录新增
        long recordAdd = jbFollowupRecordService.count(Wrappers.lambdaQuery(JbFollowupRecord.class)
                .ge(StringUtils.isNotBlank(page.getStartTimeBuilder())
                        , JbFollowupRecord::getCreateTime, page.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(page.getEndTimeBuilder())
                        , JbFollowupRecord::getCreateTime, page.getEndTimeBuilder())
                .eq(ObjectUtils.isNotEmpty(userId)
                        , JbFollowupRecord::getCreateBy, userId)
                .eq(JbFollowupRecord::getDataType, Constants.PUBLIC_NUMBER_1));
        //订单新增
        long orderAdd = jbOrderService.count(Wrappers.lambdaQuery(JbOrder.class)
                .ge(StringUtils.isNotBlank(page.getStartTimeBuilder())
                        , JbOrder::getCreateTime, page.getStartTimeBuilder())
                .le(StringUtils.isNotBlank(page.getEndTimeBuilder())
                        , JbOrder::getCreateTime, page.getEndTimeBuilder())
                .eq(ObjectUtils.isNotEmpty(userId)
                        , JbOrder::getCreateBy, userId));
        data.put("customerAdd", customerAdd);
        data.put("opportUnityAdd", opportUnityAdd);
        data.put("recordAdd", recordAdd);
        data.put("orderAdd", orderAdd);
        return success(data);
    }

    /**
     * 查询全部客户列表
     */
    @ApiOperation("查询全部客户列表")
    @GetMapping("/allList")
    public TableDataInfo allList(JbCustomer jbCustomer)
    {
        LambdaQueryWrapper<JbCustomer> wrapper = Wrappers.lambdaQuery(jbCustomer);
        if (StringUtils.isNotBlank(jbCustomer.getCustomerName()))
        {
            wrapper.like(JbCustomer::getCustomerName, jbCustomer.getCustomerName());
            jbCustomer.setCustomerName(null);
        }
        wrapper.orderByDesc(JbCustomer::getId);
        return getDataTable(service.list(wrapper));
    }


    /**
     * 获取客户详细信息
     */
    @ApiOperation("获取客户详细信息")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        JbCustomer byId = service.getById(id);
        JbCustomerListVo jbCustomerListVo = BeanUtil.toBean(byId, JbCustomerListVo.class);
        SysUser one = sysUserService.getOne(Wrappers.lambdaQuery(SysUser.class)
                .eq(SysUser::getUserId, byId.getBusinessManagerId())
                .select(SysUser::getUserName));
        jbCustomerListVo.setBusinessManagerName(Optional.ofNullable(one).map(a -> a.getUserName()).orElse(null));
        return success(jbCustomerListVo);
    }

    /**
     * 新增客户
     */
    @ApiOperation("新增客户")
    @Log(title = "新增客户", businessType = BusinessType.INSERT)
    @BusinessOperLog(title = "新增客户", businessType = BusinessType.INSERT, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PostMapping
    public AjaxResult add(@RequestBody JbCustomerDto jbCustomerDto)
    {
        Long id = service.saveInfo(jbCustomerDto);
        if (ObjectUtils.isNotEmpty(id))
        {
            return AjaxResult.success(id);
        }
        return AjaxResult.error();
    }

    /**
     * 修改客户
     */
    @ApiOperation("修改客户")
    @Log(title = "修改客户", businessType = BusinessType.UPDATE)
    @BusinessOperLog(title = "修改客户", businessType = BusinessType.UPDATE, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PutMapping
    public AjaxResult edit(@RequestBody JbCustomerUpdateDto jbCustomerUpdateDto)
    {
        return toAjax(service.updateInfoById(jbCustomerUpdateDto));
    }

    /**
     * 客户查重
     */
    @ApiOperation("客户查重")
    @GetMapping(value = "/customerIsExist/{phoneNumber}")
    public AjaxResult customerIsExist(@PathVariable("phoneNumber") String phoneNumber)
    {
        //查询订单这个客户是否有提交订单
        service.customerIsExist(phoneNumber);
        //查询是否存在客户
        long count = service.count(new LambdaQueryWrapper<JbCustomer>().eq(JbCustomer::getPhoneNumber, phoneNumber));
        if (count > 0)
        {
            return AjaxResult.error(BusinessErrorEnum.CUSTOMER_CHECK_10001.getCode(), String.format(BusinessErrorEnum.CUSTOMER_CHECK_10001.getMsg(), count));
        }

        return success(count);
    }

    /**
     * 修改客户
     */
    @ApiOperation("修改成无效客户")
    @Log(title = "修改成无效客户", businessType = BusinessType.UPDATE)
    @BusinessOperLog(title = "修改成无效客户", businessType = BusinessType.UPDATE, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PutMapping("/invalidCustomer/{id}")
    public AjaxResult invalidCustomer(@PathVariable("id") Long id)
    {
        JbCustomer update = new JbCustomer();
        update.setId(id);
        update.setIsInvalid(Constants.PUBLIC_NUMBER_1);
        update.setDataType(Constants.PUBLIC_NUMBER_3);
        return toAjax(service.updateById(update));
    }

    @ApiOperation("我的客户-转移客户")
    @Log(title = "我的客户-转移客户", businessType = BusinessType.UPDATE)
    @BusinessOperLog(title = "我的客户-转移客户", businessType = BusinessType.UPDATE, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PutMapping("/transferCustomer")
    public AjaxResult transferCustomer(@RequestBody JbCustomerTransferDto jbCustomerTransferDto)
    {
        jbCustomerTransferDto.setOpType(Constants.PUBLIC_NUMBER_0);
        jbCustomerTransferDto.setDataType(Constants.PUBLIC_NUMBER_0);
        return toAjax(service.transferCustomer(jbCustomerTransferDto));
    }

    @ApiOperation("移入公海")
    @Log(title = "移入公海", businessType = BusinessType.UPDATE)
    @PutMapping("/transferHighSeas")
    public AjaxResult transferHighSeas(@RequestBody JbCustomerTransferDto jbCustomerTransferDto)
    {
        long count = service.count(Wrappers.lambdaQuery(JbCustomer.class)
                .eq(JbCustomer::getDataType, Constants.PUBLIC_NUMBER_0)
                .in(JbCustomer::getId, jbCustomerTransferDto.getIds()));
        if (count==0){
            return error("此客户已经操作！");
        }
        //主管以上，转移到公司公海，以下部门公海
        jbCustomerTransferDto.setDataType(Constants.PUBLIC_NUMBER_1);
        jbCustomerTransferDto.setDataTypeTime(new Date());
        SysUser user = getLoginUser().getUser();
        if (!SecurityUtils.hasRole(RoleEnum.ADMIN.getCode()))
        {
            if (ObjectUtils.isEmpty(user.getRoleIds()) || SecurityUtils.hasRole(RoleEnum.MANAGER.getCode())
                    || SecurityUtils.hasRole(RoleEnum.GROUPLEADER.getCode())
                    || SecurityUtils.hasRole(RoleEnum.COMMON.getCode()))
            {
                jbCustomerTransferDto.setDataType(Constants.PUBLIC_NUMBER_2);
                jbCustomerTransferDto.setDataTypeTime(new Date());
            }
        }
        return toAjax(service.transferHighSeas(jbCustomerTransferDto));
    }

    @ApiOperation("重点关注")
    @Log(title = "重点关注", businessType = BusinessType.UPDATE)
    @BusinessOperLog(title = "重点关注", businessType = BusinessType.UPDATE, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PutMapping("/favorite/{customerId}")
    public AjaxResult favorite(@PathVariable("customerId") Long customerId)
    {
        long count = jbFavoriteTableService.count(Wrappers.lambdaQuery(JbFavoriteTable.class)
                .eq(JbFavoriteTable::getType, Constants.PUBLIC_NUMBER_2)
                .eq(JbFavoriteTable::getRelatedId, customerId));
        if (count > 0)
        {
            //表示已经存在，则直接返回ture
            return toAjax(true);
        }
        JbFavoriteTable jbFavoriteTable = new JbFavoriteTable();
        Long userId = getUserId();
        jbFavoriteTable.setType(Constants.PUBLIC_NUMBER_2);
        jbFavoriteTable.setUserId(userId);
        jbFavoriteTable.setRelatedId(customerId);
        return toAjax(jbFavoriteTableService.save(jbFavoriteTable));
    }

    @ApiOperation("取消重点关注")
    @Log(title = "取消重点关注", businessType = BusinessType.UPDATE)
    @BusinessOperLog(title = "取消重点关注", businessType = BusinessType.UPDATE, operModule = BusinessOperModule.CUSTOMER_OPER)
    @PutMapping("/cancelFavorite/{id}")
    public AjaxResult cancelFavorite(@PathVariable("id") Long id)
    {
        return toAjax(jbFavoriteTableService.removeById(id));
    }


    /**
     * 查询客户动态列表
     */
    @ApiOperation("查询客户360动态列表")
    @GetMapping("/customerDynamicList")
    public TableDataInfo customerDynamicList(PageParam page, JbCustomerListDto jbCustomerListDto)
    {
        IPage<CustomerDynamicListVo> iPage = service.customerDynamicList(page.b(), jbCustomerListDto);
        return JoR.getDataTable(iPage);
    }

    @ApiOperation("客户360详细")
    @GetMapping(value = "/detailedInforMtion/{id}")
    public AjaxResult detailedInforMtion(@PathVariable("id") Long id)
    {
        return success(service.detailedInforMtion(id));
    }

    /**
     * 查询重点客户列表
     */
    @ApiOperation("查询重点客户列表")
    @GetMapping("/favoriteCustomerList")
    public TableDataInfo favoriteCustomerList(PageParam page, JbCustomerListDto jbCustomerListDto)
    {
        if (ObjectUtils.isEmpty(jbCustomerListDto.getBusinessManagerId()))
        {
            jbCustomerListDto.setBusinessManagerId(getUserId());
        }
        jbCustomerListDto.setDataType(Constants.PUBLIC_NUMBER_0);
        jbCustomerListDto.setCreateBy(getUserId());
        IPage<JbCustomerListVo> iPage = service.favoriteSeniorListData(page.b(), jbCustomerListDto);
        return JoR.getDataTable(iPage);
    }

    /**
     * 查询重点客户列表
     */
    @ApiOperation("查询客户归属记录")
    @GetMapping("/belongToRecord/{id}")
    public TableDataInfo belongToRecord(@PathVariable("id") Long id, PageParam page)
    {
        JbCustomer jbCustomer = new JbCustomer();
        jbCustomer.setId(id);
        IPage<JbCustomerBelongToRecordVo> iPage = service.belongToRecord(page.b(), jbCustomer);
        return JoR.getDataTable(iPage);
    }

    /**
     * 查询设置筛选字段
     */
    @ApiOperation("查询设置筛选字段")
    @GetMapping("/setFieldList")
    public AjaxResult setFieldList()
    {
        return success(service.setFieldList());
    }

    /**
     * 添加和修改设置筛选字段
     */
    @ApiOperation("添加或修改设置字段")
    @Log(title = "添加或修改设置字段", businessType = BusinessType.INSERT)
    @PostMapping("/setFieldSave")
    public AjaxResult setFieldSave(@RequestBody List<JbCustomerField> jbCustomerFields)
    {
        return toAjax(service.setFieldSave(jbCustomerFields));
    }

    /**
     * 快速设置添加
     */
    @ApiOperation("添加或修改设置字段")
    @Log(title = "添加或修改设置字段", businessType = BusinessType.INSERT)
    @PostMapping("/fastSearchSave")
    public AjaxResult fastSearchSave(@RequestBody JbCustomerFastSearch jbCustomerFastSearch)
    {
        return toAjax(service.fastSearchSave(jbCustomerFastSearch));
    }

    /**
     * 查询设置快速设置
     */
    @ApiOperation("查询设置筛选字段")
    @GetMapping("/fastSearchList")
    public AjaxResult fastSearchList()
    {
        return success(service.fastSearchList());
    }

    /**
     * 删除设置快速设置
     */
    @ApiOperation("删除设置快速设置")
    @Log(title = "删除设置快速设置", businessType = BusinessType.DELETE)
    @DeleteMapping("/fastSearchDel/{id}")
    public AjaxResult fastSearchDel(@PathVariable("id") Long id)
    {
        return success(service.fastSearchDel(id));
    }

    /**
     * 快速设置天置顶
     */
    @ApiOperation("快速设置天置顶")
    @Log(title = "快速设置天置顶", businessType = BusinessType.UPDATE)
    @PutMapping("/fastTopUp/{id}")
    public AjaxResult fastTopUp(@PathVariable("id") Long id)
    {
        return success(service.fastTopUp(id));
    }

    /**
     * 查询设置快速详细
     */
    @ApiOperation("查询设置快速详细")
    @GetMapping("/fastSearchInfo/{id}")
    public AjaxResult fastSearchInfo(@PathVariable("id") Long id)
    {
        return success(service.fastSearchInfo(id));
    }

    /**
     * 详情的更多
     */
    @ApiOperation("详情的更多")
    @GetMapping("/detailsMore/{id}")
    public AjaxResult detailsMore(@PathVariable("id") Long id)
    {
        return success(service.detailsMore(id));
    }

    /**
     * 退款记录
     */
    @ApiOperation("退款记录")
    @GetMapping("/refundList")
    public TableDataInfo refundList(JbRefund jbRefund)
    {
        startPage();
        LambdaQueryWrapper<JbRefund> queryWrapper = Wrappers.lambdaQuery(jbRefund);
        queryWrapper.orderByDesc(JbRefund::getId);
        return getDataTable(jbRefundService.list(queryWrapper));
    }

    /**
     * 操作日志记录
     */

    @ApiOperation("操作日志记录")
    @GetMapping("/operRecordList")
    public TableDataInfo operRecordList(JbBusinessOperRecord jbBusinessOperRecord)
    {
        startPage();
        LambdaQueryWrapper<JbBusinessOperRecord> queryWrapper = Wrappers.lambdaQuery(jbBusinessOperRecord);
        queryWrapper.orderByDesc(JbBusinessOperRecord::getId);
        return getDataTable(jbBusinessOperRecordService.list(queryWrapper));
    }
    /**
     * 获取客户详细信息
     */
    @ApiOperation("获取客户详细信息")
    @PreAuthorize("@ss.hasPermi('customer:query')")
    @GetMapping(value = "/detailsInfo/{id}")
    public AjaxResult detailsInfo(@PathVariable("id") Long id)
    {
        return success(service.detailsInfo(id));
    }
}
